package com.vip8.recorder.service.service.impl;

import com.vip8.recorder.api.model.base.MultiResult;
import com.vip8.recorder.api.model.dto.AppVersionDTO;
import com.vip8.recorder.api.model.dto.HeartbeatDTO;
import com.vip8.recorder.api.model.params.DeviceParams;
import com.vip8.recorder.api.model.params.VersionParam;
import com.vip8.recorder.service.constant.ValidEnum;
import com.vip8.recorder.service.db.mapper.AppVersionDao;
import com.vip8.recorder.service.db.mapper.DeviceInfoDao;
import com.vip8.recorder.service.db.mapper.HeartbeatDao;
import com.vip8.recorder.service.db.model.*;
import com.vip8.recorder.service.service.DeviceService;
import com.vip8.recorder.service.service.OssManageService;
import com.vip8.recorder.service.utils.BeanCopyUtil;
import com.vip8.recorder.service.utils.CollectionUtil;
import com.vip8.recorder.service.utils.DateUtil;
import com.vip8.recorder.service.utils.StringUtil;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DeviceServiceImpl implements DeviceService {
    @Resource
    private DeviceInfoDao deviceInfoDao;

    @Resource
    private AppVersionDao versionDao;

    @Resource
    private HeartbeatDao heartbeatDao;

    @Resource
    private OssManageService ossManageService;


    @Override
    public Boolean heartbeat(DeviceParams deviceParams) {

        Heartbeat heartbeat = new Heartbeat();
        heartbeat.setDeviceId(deviceParams.getDeviceId());
        heartbeat.setAddress(deviceParams.getAddress());
        heartbeat.setCity(deviceParams.getCity());
        if(StringUtil.isNotEmpty(deviceParams.getPhone())){
            heartbeat.setPhone(deviceParams.getPhone());
        }
        if(StringUtil.isNotEmpty(deviceParams.getEmpName())){
            heartbeat.setEmpName(deviceParams.getEmpName());
        }
        if(StringUtil.isNotEmpty(deviceParams.getEmployeeId())){
            heartbeat.setEmployeeId(deviceParams.getEmployeeId());
        }
        if(deviceParams.getHeartbeatTime() != null){
            heartbeat.setHeartbeatTime(deviceParams.getHeartbeatTime());
        }
        if(deviceParams.getType() != null){
            heartbeat.setType(deviceParams.getType().byteValue());
        }
        heartbeat.setPoint(deviceParams.getPoint());
        heartbeatDao.insertSelective(heartbeat);

        DeviceInfo record = new DeviceInfo();
        BeanCopyUtil.copyBean(deviceParams, record);
        DeviceInfoExample example = new DeviceInfoExample();
        example.createCriteria().andDeviceIdEqualTo(deviceParams.getDeviceId());

        List<DeviceInfo> deviceInfos = deviceInfoDao.selectByExample(example);
        if (CollectionUtil.isEmpty(deviceInfos)) {
            deviceInfoDao.insertSelective(record);
        } else {
            record.setDeviceId(null);
            record.setLastRecord(new Date());
            deviceInfoDao.updateByExampleSelective(record, example);
        }
        return true;
    }

    @Override
    public Boolean batchHeartbeat(List<DeviceParams> deviceParams) {
        if(CollectionUtil.isEmpty(deviceParams)){
            return false;
        }
        deviceParams.forEach((this::heartbeat));
        return true;
    }

    @Override
    public AppVersionDTO checkVersion(VersionParam param) {
        AppVersionExample example = new AppVersionExample();
        example.createCriteria().andVersionGreaterThan(param.getVersion()).andValidEqualTo(ValidEnum.VALID.getFlag());
        example.setOrderByClause(" `version` desc");
        List<AppVersion> versions = versionDao.selectByExample(example);
        if (CollectionUtil.isEmpty(versions)) {
            return null;
        }
        AppVersionDTO versionDTO = new AppVersionDTO();
        AppVersion version = versions.get(0);
        BeanCopyUtil.copyBean(version, versionDTO);
        String url = ossManageService.getUrlByFileKey(version.getDownloadUrl(), DateUtil.addMonth(new Date(), 1),null );
        versionDTO.setDownloadUrl(url);

        return versionDTO;
    }

    @Override
    public MultiResult<HeartbeatDTO> queryPersonDistribution(DeviceParams deviceParams) {

        HeartbeatExample example = new HeartbeatExample();
        HeartbeatExample.Criteria criteria = example.createCriteria();
        if (deviceParams.getStartTime() != null && deviceParams.getEndTime() != null) {
            criteria.andHeartbeatTimeBetween(deviceParams.getStartTime(), deviceParams.getEndTime());
        }
        if (StringUtil.isNotEmpty(deviceParams.getEmpName())) {
            criteria.andEmpNameLike("%" + deviceParams.getEmpName() + "%");
        }
        if (StringUtil.isNotEmpty(deviceParams.getPhone())) {
            criteria.andPhoneEqualTo(deviceParams.getPhone());
        }
        if (StringUtil.isNotEmpty(deviceParams.getCity())) {
            criteria.andCityLike("%" +deviceParams.getCity()+ "%");
        }
        if(StringUtil.isNotEmpty(deviceParams.getEmployeeId())){
            criteria.andEmployeeIdEqualTo(deviceParams.getEmployeeId());
        }
        int offset = 0;
        if (deviceParams.getStartPage() != null) {
            offset = deviceParams.getStartPage() < 1 ? 0 : (deviceParams.getStartPage() - 1) * deviceParams.getPageSize();
        }
        criteria.andEmployeeIdIsNotNull();
        example.setOffset((long) offset);
        example.setLimit(deviceParams.getPageSize());
        List<Heartbeat> heartbeats = heartbeatDao.selectDistributionByExample(example);

        if (CollectionUtil.isNotEmpty(heartbeats)) {
            long total = heartbeatDao.countDistributionByExample(example);
            List<HeartbeatDTO> heartbeatDTOS = heartbeats.stream().map(this::coverToHeartbeatDTO).collect(Collectors.toList());

            return MultiResult.success(heartbeatDTOS, (int) total);

        }
        return MultiResult.success(null, 0);
    }

    @Override
    public MultiResult<HeartbeatDTO> queryTrack(DeviceParams deviceParams) {
        HeartbeatExample example = new HeartbeatExample();
        HeartbeatExample.Criteria criteria = example.createCriteria();
        if (deviceParams.getStartTime() != null && deviceParams.getEndTime() != null) {
            criteria.andHeartbeatTimeBetween(deviceParams.getStartTime(), deviceParams.getEndTime());
        }
        if (StringUtil.isNotEmpty(deviceParams.getEmpName())) {
            criteria.andEmpNameLike("%" + deviceParams.getEmpName() + "%");
        }
        if (StringUtil.isNotEmpty(deviceParams.getPhone())) {
            criteria.andPhoneEqualTo(deviceParams.getPhone());
        }
        if (StringUtil.isNotEmpty(deviceParams.getCity())) {
            criteria.andCityLike("%" + deviceParams.getCity() + "%");
        }
        if(StringUtil.isNotEmpty(deviceParams.getEmployeeId())){
            criteria.andEmployeeIdEqualTo(deviceParams.getEmployeeId());
        }
        int offset = 0;
        if (deviceParams.getStartPage() != null) {
            offset = deviceParams.getStartPage() < 1 ? 0 : (deviceParams.getStartPage() - 1) * deviceParams.getPageSize();
        }
        example.setOffset((long) offset);
        example.setLimit(deviceParams.getPageSize());
        List<Heartbeat> heartbeats = heartbeatDao.selectTrackByExample(example);
        if (CollectionUtil.isNotEmpty(heartbeats)) {
            long total = heartbeatDao.countTrackByExample(example);
            List<HeartbeatDTO> heartbeatDTOS = heartbeats.stream().map(this::coverToHeartbeatDTO).collect(Collectors.toList());

            return MultiResult.success(heartbeatDTOS, (int) total);
        }
        return MultiResult.success(null, 0);
    }

    private HeartbeatDTO coverToHeartbeatDTO(Heartbeat item){
        HeartbeatDTO heartbeatDTO = new HeartbeatDTO();
        BeanCopyUtil.copyBean(item, heartbeatDTO);
        heartbeatDTO.setTimestamp(item.getHeartbeatTime());
        if(StringUtil.isEmpty(item.getAddress())){
            heartbeatDTO.setAddress("未定位成功");
        }
        return heartbeatDTO;
    }
}
